// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: xguo

#include <gflags/gflags.h>
#include <google/protobuf/util/json_util.h>
#include <nlohmann/json.hpp>

#include "coin2/base/date_util.h"
#include "coin2/base/hostname_util.h"
#include "coin2/exchange/base/log/order_logger.h"
#include "coin2/exchange/base/log/strategy_logger.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/base/market/market_exchange_api.h"

DEFINE_string(strategy_id, "", "Specify the strategy id.");

DEFINE_string(strategy_name, "", "Specify strategy name.");

DEFINE_string(log_root, "~/data/strat_proto_log", "Specify Strat log root.");

DEFINE_string(machine, "", "Specify machine name.");

DEFINE_string(trading_date, "", "Specify trading date.");

std::string ProtoToJson(const google::protobuf::Message& message) {
  google::protobuf::util::JsonPrintOptions options;
  options.add_whitespace = true;
  options.always_print_primitive_fields = false;
  options.preserve_proto_field_names = true;

  std::string json_string;
  google::protobuf::util::MessageToJsonString(message, &json_string, options);
  return json_string;
}

int64_t DateStrToTimestamp(const std::string& date_str) {
  CHECK(coin2::exchange::base::symbology::IsDateStr(date_str)) << date_str;
  auto year = std::stoi(date_str.substr(0, 4));
  auto month = std::stoi(date_str.substr(4, 2));
  auto day = std::stoi(date_str.substr(6, 2));
  boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
  boost::posix_time::ptime date_time(boost::gregorian::date(year, month, day));
  return (date_time - epoch).total_seconds() * 1e9;
}

int main(int argc, char* argv[]) {
  using coin::proto::StrategyRequestProto;
  using coin2::exchange::base::strategy_util::StrategyLogReader;
  using namespace coin2::exchange::base::market;

  google::InitGoogleLogging(argv[0]);
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  CHECK_EQ(FLAGS_strategy_name.empty(), false);
  CHECK_EQ(FLAGS_machine.empty(), false);
  CHECK_EQ(FLAGS_trading_date.empty(), false);

  StrategyRequestProto req_proto;
  req_proto.set_strategy_id(0);
  req_proto.set_strategy_name(FLAGS_strategy_name);
  req_proto.set_strategy_group("");
  req_proto.set_trader("");
  auto begin = DateStrToTimestamp(FLAGS_trading_date);
  auto end = begin + static_cast<int64_t>(24 * 3600 * 1e9);

  coin::proto::StrategyLog proto;
  auto log_root = ExpandUser(FLAGS_log_root);
  StrategyLogReader proto_reader(req_proto, log_root, FLAGS_machine, begin, end, 8192 * 800);
  int64_t ts;
  while (proto_reader.Read(&proto)) {
    auto json_str = ProtoToJson(proto);
    auto content = nlohmann::json::parse(json_str);
    nlohmann::json wrapper;
    wrapper["data"] = content;
    wrapper["timestamp"] = ts;
    std::cout << wrapper.dump(4) << std::endl;
  }
  return 0;
}
